/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.jm.mala.view;

import br.jm.mala.entity.CepBairro;
import br.jm.mala.entity.CepCidade;
import br.jm.mala.entity.CepEndereco;
import br.jm.mala.entity.CepUf;
import br.jm.mala.lazyModel.GenericLazyDataModel;
import br.jm.mala.lazyModel.GenericLazyDataModelLocal;
import br.jm.mala.service.CepBairroService;
import br.jm.mala.service.CepCidadeService;
import br.jm.mala.service.CepEnderecoService;
import br.jm.mala.service.CepUfService;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.context.RequestContext;
import org.primefaces.model.LazyDataModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.talesolutions.cep.CEP;
import org.talesolutions.cep.CEPService;
import org.talesolutions.cep.CEPServiceFactory;

/**
 *
 * @author joao
 */
@Component("cepEnderecoView")
@Scope("view")
public class CepEnderecoView implements Serializable {

    private static final long serialVersionUID = 7211518890591883404L;
    private final CepEnderecoService cepEnderecoService;
    private final CepBairroService cepBairroService;
    private final CepCidadeService cepCidadeService;
    private final CepUfService cepUfService;
    private LazyDataModel<CepEndereco> cepEnderecoLazy;
    private LazyDataModel<CepBairro> cepBairroLazy;
    private CepEndereco selectedCepEndereco;
    private CepBairro selectedBairro = new CepBairro();
    private FacesMessage msg;
    private String numeroCep;
    private String descLogradouro;
    private List<CEP> ceps;
    private LazyDataModel<CEP> lazyCeps;
    private CEP cep;

    @Autowired
    public CepEnderecoView(CepEnderecoService cepEnderecoService, CepBairroService cepBairroService, CepCidadeService cepCidadeService, CepUfService cepUfService) {
        this.cepEnderecoService = cepEnderecoService;
        this.cepBairroService = cepBairroService;
        this.cepCidadeService = cepCidadeService;
        this.cepUfService = cepUfService;

        this.cepBairroLazy = new GenericLazyDataModel(cepBairroService, null, null, "CepBairro");
        this.cepEnderecoLazy = new GenericLazyDataModel(cepEnderecoService, null, null, "CepEndereco");

        this.selectedBairro = new CepBairro();
        this.selectedCepEndereco = new CepEndereco();
        this.selectedCepEndereco.setCodBairro(new CepBairro());
        this.selectedCepEndereco.getCodBairro().setCodCidade(new CepCidade());
        this.selectedCepEndereco.getCodBairro().getCodCidade().setCodUf(new CepUf());
        MenuView.salvar = true;

    }

    public LazyDataModel<CepEndereco> getCepEnderecoLazy() {
        return cepEnderecoLazy;
    }

    public void setCepEnderecoLazy(LazyDataModel<CepEndereco> cepEnderecoLazy) {
        this.cepEnderecoLazy = cepEnderecoLazy;
    }

    public CepEndereco getSelectedCepEndereco() {
        return selectedCepEndereco;
    }

    public void setSelectedCepEndereco(CepEndereco selectedCepEndereco) {
        RequestContext context = RequestContext.getCurrentInstance();
        this.descLogradouro = "";
        this.numeroCep = "";
        this.ceps = new ArrayList<>();
        this.lazyCeps = new GenericLazyDataModelLocal(ceps);
        context.update("frmPrincipal:tabCep");
        context.update("frmPrincipal:panelCep");
        this.selectedCepEndereco = selectedCepEndereco;
    }

    public void preparaInserir(ActionEvent event) {
        RequestContext context = RequestContext.getCurrentInstance();
        MenuView.salvar = true;
        this.ceps = new ArrayList<>();
        this.lazyCeps = new GenericLazyDataModelLocal(ceps);
        this.descLogradouro = "";
        this.numeroCep = "";
        this.selectedCepEndereco = new CepEndereco();
        this.selectedCepEndereco.setCodBairro(new CepBairro());
        this.selectedCepEndereco.getCodBairro().setCodCidade(new CepCidade());
        this.selectedCepEndereco.getCodBairro().getCodCidade().setCodUf(new CepUf());
        context.update("frmPrincipal:tabCep");
        context.update("frmPrincipal:panelCep");
    }

    public void inserir(ActionEvent actionEvent) {
        msg = null;

        try {
            this.selectedCepEndereco.setCodLogradouro(null);
            this.cepEnderecoService.create(selectedCepEndereco);

            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Endereço Inserido com Sucesso", this.selectedCepEndereco.getDscLogradouro());
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Inserir", this.selectedCepEndereco.getDscLogradouro());
        } finally {
            preparaInserir(actionEvent);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void alterar(ActionEvent actionEvent) {
        msg = null;
        try {
            this.cepEnderecoService.edit(selectedCepEndereco);
            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Endereço Alterado com Sucesso", this.selectedCepEndereco.getDscLogradouro());
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao Alterar", this.selectedCepEndereco.getDscLogradouro());
        } finally {
            preparaInserir(actionEvent);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public void excluir(ActionEvent actionEvent) {
        msg = null;

        try {
            this.cepEnderecoService.destroy(selectedCepEndereco);

            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Endereço Excluido com Sucesso", this.selectedCepEndereco.getDscLogradouro());
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Erro ao Excluir: " + this.selectedCepEndereco.getDscLogradouro(), "ENDEREÃ‡O SENDO UTILIZADO EM ALGUM PROCESSO!");
        } finally {
            preparaInserir(actionEvent);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }

    public CepBairro getSelectedBairro() {
        return selectedBairro;
    }

    public void setSelectedBairro(CepBairro selectedBairro) {
        this.selectedCepEndereco.setCodBairro(selectedBairro);
        this.selectedBairro = selectedBairro;
    }

    public LazyDataModel<CepBairro> getCepBairroLazy() {
        return cepBairroLazy;
    }

    public void setCepBairroLazy(LazyDataModel<CepBairro> cepBairroLazy) {
        this.cepBairroLazy = cepBairroLazy;
    }

    public String getNumeroCep() {
        return numeroCep;
    }

    public void setNumeroCep(String numeroCep) {
        this.numeroCep = numeroCep;
    }

    public String getDescLogradouro() {
        return descLogradouro;
    }

    public void setDescLogradouro(String descLogradouro) {
        this.descLogradouro = descLogradouro;
    }

    public LazyDataModel<CEP> getLazyCeps() {
        return lazyCeps;
    }

    public void setLazyCeps(LazyDataModel<CEP> lazyCeps) {
        this.lazyCeps = lazyCeps;
    }

    public void PesquisarEndereco(ActionEvent actionEvent) {
        RequestContext context = RequestContext.getCurrentInstance();
        msg = null;
        ceps = new ArrayList<>();
        // Obtem uma instancia de CEPService
        CEPService buscaCEP = CEPServiceFactory.getCEPService();

        this.numeroCep = this.numeroCep.replace("-", "");
        try {
            if (!this.numeroCep.isEmpty()) {
                ceps = buscaCEP.obtemPorNumeroCEPList(this.numeroCep);
                if (ceps.isEmpty()) {
                    msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Endereço não Encontrado!", "Tente Novamente! - ".concat(this.descLogradouro));
                } else {
                    msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Pesquisa Efetuada com Sucesso!", this.descLogradouro);
                }
            } else if (!this.descLogradouro.isEmpty()) {
                // Obtem todos os CEPs que  no logradouro
                ceps = buscaCEP.obtemPorEndereco(this.descLogradouro);
                if (ceps.isEmpty()) {
                    msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Endereço não Encontrado!", "Tente Novamente! - ".concat(this.descLogradouro));
                } else {
                    msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Pesquisa Efetuada com Sucesso!", this.descLogradouro);
                }
            } else {
                msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "ATENÇÃO ... Obrigatório preencher um dos Campos de Pesquisa", "");
            }
        } catch (Exception e) {
            msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Erro ao Pesquisar o Endereço!", "");
        } finally {
            lazyCeps = new GenericLazyDataModelLocal(ceps);
            FacesContext.getCurrentInstance().addMessage(null, msg);
            context.update("frmPrincipal:tabCep");
            context.update("frmPrincipal:panelCep");
        }
    }

    public CEP getCep() {
        return cep;
    }

    public void setCep(CEP cep) {
        this.cep = cep;
    }

    public void selecionaEndereco() {
        RequestContext context = RequestContext.getCurrentInstance();
        // VERIFICA ESTADO
        CepUf cepUf;
        try {
            cepUf = this.cepUfService.getPorId(this.cep.getUf());
        } catch (Exception e) {
            cepUf = null;
        }
        if (cepUf == null) {
            cepUf = new CepUf();
            cepUf = new CepUf();
            cepUf.setCodUf(this.cep.getUf());
            cepUf.setDscEstado(this.cep.getLocalidade());
            this.cepUfService.create(cepUf);
        }
        // VERIFICA CIDADE
        CepCidade cepCidade;
        try {
            cepCidade = this.cepCidadeService.getNativeFiltro("select cod_cidade,dsc_cidade,cod_uf from cep_cidade where dsc_cidade = '".concat(this.cep.getLocalidade()).concat("'"));
        } catch (Exception e) {
            cepCidade = null;
        }
        if (cepCidade == null) {
            cepCidade = new CepCidade();
            cepCidade.setCodCidade(null);
            cepCidade.setCodUf(cepUf);
            cepCidade.setDscCidade(this.cep.getLocalidade());
            this.cepCidadeService.create(cepCidade);
        }
        // VERIFICA BAIRRO
        CepBairro cepBairro;
        try {
            cepBairro = this.cepBairroService.getNativeFiltro("select cod_bairro,dsc_bairro,cod_cidade from cep_bairro where dsc_bairro = '".concat(this.cep.getBairro()).concat("'"));
        } catch (Exception e) {
            cepBairro = null;
        }
        if (cepBairro == null) {
            cepBairro = new CepBairro();
            cepBairro.setCodBairro(null);
            cepBairro.setCodCidade(cepCidade);
            cepBairro.setDscBairro(this.cep.getBairro());
            this.cepBairroService.create(cepBairro);
        }
        // VERIFICA ENDERECO
        CepEndereco cepEndereco;
        try {
            cepEndereco = this.cepEnderecoService.getNativeFiltro("select cod_logradouro,dsc_logradouro,num_cep,cod_bairro from cep_Endereco where dsc_logradouro = '".concat(this.cep.getLogradouro()).concat("'"));
        } catch (Exception e) {
            cepEndereco = null;
        }
        if (cepEndereco == null) {
            cepEndereco = new CepEndereco();
            cepEndereco.setCodBairro(new CepBairro());
            cepEndereco.getCodBairro().setCodCidade(new CepCidade());
            cepEndereco.getCodBairro().getCodCidade().setCodUf(new CepUf());

            cepEndereco.getCodBairro().getCodCidade().setCodUf(cepUf);
            cepEndereco.getCodBairro().setCodCidade(cepCidade);
            cepEndereco.setCodBairro(cepBairro);
            cepEndereco.setCodLogradouro(null);
            cepEndereco.setDscLogradouro(this.cep.getLogradouro());
            cepEndereco.setNumCep(this.cep.getNumero());
        }
        this.numeroCep = "";
        this.descLogradouro = "";
        this.ceps = new ArrayList<>();
        this.lazyCeps = new GenericLazyDataModelLocal(ceps);

        this.selectedCepEndereco = cepEndereco;

        context.update("frmPrincipal:tabCep");
        context.update("frmPrincipal:panelCep");
    }
}
